# 前言
上一小节我们介绍完了关于模版是如何编译成 AST 的结构的,接下来进入模版编译的第二步 transform,transform 的目标是为了生成 JavaScript AST。因为渲染函数是一堆 js 代码构成的,编译器最终产物就是渲染函数,所以理想中的 AST 应该是用来描述渲染函数的 JS 代码。
那么接下来,我们一起看看 transfrom 转换的实现细节吧!
# Transform
function baseCompile(template, options) {
const isModuleMode = options.mode === 'module'
// 用来标记代码生成模式
const prefixIdentifiers =
!__BROWSER__ && (options.prefixIdentifiers === true || isModuleMode)
// 获取节点和指令转换的方法
const [nodeTransforms, directiveTransforms] = getBaseTransformPreset()
// AST 转换成 Javascript AST
transform(
ast,
extend({}, options, {
prefixIdentifiers,
nodeTransforms: [
...nodeTransforms,
...(options.nodeTransforms || [])
],
directiveTransforms: extend(
{},
directiveTransforms,
options.directiveTransforms || {}
)
})
)
}
@前端进阶之旅: 代码已经复制到剪贴板
其中第一个参数 prefixIdentifiers 是用于标记前缀代码生成模式的。举个例子,以下代码:
html
复制代码<div>
{{msg}}
</div>
@前端进阶之旅: 代码已经复制到剪贴板
在 module 模式下,生成的渲染函数是一个通过 with(_ctx) { ... } 包裹后的,大致为:
return function render(_ctx) {
with (_ctx) {
const { toDisplayString, openBlock, createElementBlock } = Vue
return (openBlock(), createElementBlock("div", null, toDisplayString(msg), 1 /* TEXT */))
}
}
@前端进阶之旅: 代码已经复制到剪贴板
而在 function 模式下,生成的渲染函数中的动态内容,则会被转成 _ctx.msg 的模式:
<